/*
 * StaffDBTopComponent.java
 * 
 * Created: Feb 16, 2015
 * 
 * Copyright (c) ExpertPB 2014
 * All information contained herein is, and remains the property of
 * ExpertPB and its suppliers, if any.
 */
package com.emex.app.stuff;

import com.emex.app.stuff.security.SecurityManager;
import com.emex.app.shared.data.Client;
import com.emex.app.stuff.gui.ClientDialog;
import com.emex.app.stuff.gui.model.StaffTableModel;
import com.emex.app.stuff.provider.ClientDataProvider;
import com.emex.app.stuff.utils.ExportUtils;
import com.emex.app.stuff.utils.UIUtils;
import java.awt.Frame;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.RowFilter;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;

/**
 * Top component which displays something.
 */
@ConvertAsProperties(
        dtd = "-//com.emex.app.stuff//StaffDB//EN",
        autostore = false
)
@TopComponent.Description(
        preferredID = "StaffDBTopComponent",
        //iconBase="SET/PATH/TO/ICON/HERE", 
        persistenceType = TopComponent.PERSISTENCE_NEVER
)
@TopComponent.Registration(mode = "editor", openAtStartup = false)
@ActionID(category = "Window", id = "com.emex.app.stuff.StaffDBTopComponent")
@ActionReference(path = "Menu/Клиенты" /*, position = 333 */)
@TopComponent.OpenActionRegistration(
        displayName = "#CTL_StaffDBAction",
        preferredID = "StaffDBTopComponent"
)
@Messages({
    "CTL_StaffDBAction=Клиентская база",
    "CTL_StaffDBTopComponent=Клиентская база",
    "HINT_StaffDBTopComponent=Клиентская база"
})
public final class StaffDBTopComponent extends TopComponent {

    private static Frame mainWindow = WindowManager.getDefault().getMainWindow();

    private StaffTableModel staffTableModel;

    public StaffDBTopComponent() {
        initComponents();
        setName(Bundle.CTL_StaffDBTopComponent());
        setToolTipText(Bundle.HINT_StaffDBTopComponent());
        customInit();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        filterPanel = new javax.swing.JPanel();
        searchField = new javax.swing.JTextField();
        searchButton = new javax.swing.JButton();
        cancelFilterButton = new javax.swing.JButton();
        addClientButton = new javax.swing.JButton();
        editViewClientButton = new javax.swing.JButton();
        deleteClientButton = new javax.swing.JButton();
        exportButton = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        clientsTable = new org.jdesktop.swingx.JXTable();
        refreshTableButton = new javax.swing.JButton();
        usersLabel = new javax.swing.JLabel();
        internetUsersLabel = new javax.swing.JLabel();

        filterPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.filterPanel.border.title"))); // NOI18N

        searchField.setText(org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.searchField.text")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(searchButton, org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.searchButton.text")); // NOI18N
        searchButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(cancelFilterButton, org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.cancelFilterButton.text")); // NOI18N
        cancelFilterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelFilterButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout filterPanelLayout = new javax.swing.GroupLayout(filterPanel);
        filterPanel.setLayout(filterPanelLayout);
        filterPanelLayout.setHorizontalGroup(
            filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(filterPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(searchField)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(searchButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(cancelFilterButton)
                .addContainerGap())
        );
        filterPanelLayout.setVerticalGroup(
            filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(filterPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(searchField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(searchButton)
                    .addComponent(cancelFilterButton))
                .addContainerGap())
        );

        org.openide.awt.Mnemonics.setLocalizedText(addClientButton, org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.addClientButton.text")); // NOI18N
        addClientButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addClientButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(editViewClientButton, org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.editViewClientButton.text")); // NOI18N
        editViewClientButton.setEnabled(false);
        editViewClientButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                editViewClientButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(deleteClientButton, org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.deleteClientButton.text")); // NOI18N
        deleteClientButton.setEnabled(false);
        deleteClientButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteClientButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(exportButton, org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.exportButton.text")); // NOI18N
        exportButton.setToolTipText(org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.exportButton.toolTipText")); // NOI18N
        exportButton.setEnabled(false);
        exportButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportButtonActionPerformed(evt);
            }
        });

        clientsTable.setToolTipText(org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.clientsTable.toolTipText")); // NOI18N
        clientsTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                clientsTableMouseClicked(evt);
            }
        });
        jScrollPane2.setViewportView(clientsTable);

        refreshTableButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/refresh.png"))); // NOI18N
        org.openide.awt.Mnemonics.setLocalizedText(refreshTableButton, org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.refreshTableButton.text")); // NOI18N
        refreshTableButton.setToolTipText(org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.refreshTableButton.toolTipText")); // NOI18N
        refreshTableButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                refreshTableButtonActionPerformed(evt);
            }
        });

        org.openide.awt.Mnemonics.setLocalizedText(usersLabel, org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.usersLabel.text")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(internetUsersLabel, org.openide.util.NbBundle.getMessage(StaffDBTopComponent.class, "StaffDBTopComponent.internetUsersLabel.text")); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(addClientButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(editViewClientButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(deleteClientButton)
                        .addGap(10, 10, 10)
                        .addComponent(exportButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(refreshTableButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(usersLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(internetUsersLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 159, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(67, 67, 67))
                    .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(filterPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane2)
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addClientButton)
                    .addComponent(editViewClientButton)
                    .addComponent(deleteClientButton)
                    .addComponent(exportButton)
                    .addComponent(refreshTableButton)
                    .addComponent(usersLabel)
                    .addComponent(internetUsersLabel))
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    private void addClientButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addClientButtonActionPerformed
        ClientDialog dialog = new ClientDialog(mainWindow, true);
        dialog.setStaffTableModel(staffTableModel);
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
        initStaffCount();
    }//GEN-LAST:event_addClientButtonActionPerformed

    private void editViewClientButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editViewClientButtonActionPerformed
        ClientDialog dialog = new ClientDialog(mainWindow, true);
        dialog.setClient(getClientSelection());
        dialog.setStaffTableModel(staffTableModel);
        dialog.setLocationRelativeTo(null);
        dialog.setTitle("Редактирование/Просмотр клиента");
        dialog.setVisible(true);
    }//GEN-LAST:event_editViewClientButtonActionPerformed

    private void deleteClientButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteClientButtonActionPerformed
        Client selection = getClientSelection();
        ClientDataProvider.getInstance().deleteByPrimaryKey(selection.getId());
        staffTableModel.dataRemoved(selection);
        initStaffCount();
    }//GEN-LAST:event_deleteClientButtonActionPerformed

    private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchButtonActionPerformed
        if (null != searchField.getText()
                && !searchField.getText().isEmpty()) {
            clientsTable.setRowFilter(RowFilter.andFilter(constructFilter()));
        }
    }//GEN-LAST:event_searchButtonActionPerformed

    private void cancelFilterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelFilterButtonActionPerformed
        clientsTable.setRowFilter(null);
        searchField.setText("");
    }//GEN-LAST:event_cancelFilterButtonActionPerformed

    private void clientsTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_clientsTableMouseClicked
        if (evt.getClickCount() == 2) {
            editViewClientButtonActionPerformed(null);
        }
    }//GEN-LAST:event_clientsTableMouseClicked

    private void refreshTableButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshTableButtonActionPerformed
        staffTableModel = new StaffTableModel();
        clientsTable.setModel(staffTableModel);
    }//GEN-LAST:event_refreshTableButtonActionPerformed

    private void exportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportButtonActionPerformed
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("Сохранить файл как...");
        fileChooser.setSelectedFile(new java.io.File("clientDB.xls"));
        int result = fileChooser.showSaveDialog(WindowManager.getDefault().getMainWindow());
        if (result != JFileChooser.APPROVE_OPTION) {
            return;
        }

        try {
            Files.write(fileChooser.getSelectedFile().toPath(), ExportUtils.exportToExcel(clientsTable));
        } catch (Exception ex) {
            ex.printStackTrace();
            UIUtils.showErrorMessage("Произошли ошибки при сохранении файла");
        }
    }//GEN-LAST:event_exportButtonActionPerformed

    private List<RowFilter<Object, Object>> constructFilter() {
        List<RowFilter<Object, Object>> filters = new ArrayList<>();
        filters.add(RowFilter.regexFilter(wordFromUpperCase(searchField.getText())));
        return filters;
    }

    private String wordFromUpperCase(String toUpper) {
        char[] stringArray = toUpper.trim().toCharArray();
        stringArray[0] = Character.toUpperCase(stringArray[0]);
        return new String(stringArray);
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addClientButton;
    private javax.swing.JButton cancelFilterButton;
    private org.jdesktop.swingx.JXTable clientsTable;
    private javax.swing.JButton deleteClientButton;
    private javax.swing.JButton editViewClientButton;
    private javax.swing.JButton exportButton;
    private javax.swing.JPanel filterPanel;
    private javax.swing.JLabel internetUsersLabel;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JButton refreshTableButton;
    private javax.swing.JButton searchButton;
    private javax.swing.JTextField searchField;
    private javax.swing.JLabel usersLabel;
    // End of variables declaration//GEN-END:variables
    @Override
    public void componentOpened() {
        // TODO add custom code on component opening
    }

    @Override
    public void componentClosed() {
        // TODO add custom code on component closing
    }

    void writeProperties(java.util.Properties p) {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty("version", "1.0");
        // TODO store your settings
    }

    void readProperties(java.util.Properties p) {
        String version = p.getProperty("version");
        // TODO read your settings according to their version
    }

    protected void customInit() {
        staffTableModel = new StaffTableModel();
        clientsTable.setModel(staffTableModel);
        initStaffCount();
        if (clientsTable.getRowCount() > 0) {
            if (SecurityManager.getDefault().getCurrentPerson().getIsAdmin()) {
                exportButton.setEnabled(true);
            } else {
                exportButton.setEnabled(false);
            }
        }
        clientsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                int row = clientsTable.getSelectedRow();
                if ((row >= 0) && (row < clientsTable.getRowCount())) {
                    editViewClientButton.setEnabled(true);
                    if (SecurityManager.getDefault().getCurrentPerson().getIsAdmin()) {
                        deleteClientButton.setEnabled(true);
                    } else {
                        deleteClientButton.setEnabled(false);
                    }
                } else {
                    editViewClientButton.setEnabled(false);
                    deleteClientButton.setEnabled(false);
                }
            }
        });
    }

    protected Client getClientSelection() {
        if (clientsTable.getSelectedRow() > -1) {
            Client client = (Client) clientsTable
                    .getValueAt(clientsTable.getSelectedRow(), -1);
            return client;
        }
        return null;
    }

    private void initStaffCount() {
        usersLabel.setText("Клиенты: " + staffTableModel.getUsersCount());
        internetUsersLabel.setText("Интернет-клиенты: " + staffTableModel.getInternetUsersCount());
    }
}
